/**
 * Created by Administrator on 2017/4/24.
 */

var pomelo = require('pomelo');
var roomManager = require('./roomManager');
var VirtualSession = require('./VirtualSession').VirtualSession;
var LogicSubModules = require("../../logic/sub");

var Localize = require ("../../../config/localize.json");

var province = Object.keys(Localize.Province);


function generateRobotName() {
    var randValue = Ext.rand(1000);
    var len = randValue%3 + 2;

    var name = "";
    for (var i = 0; i < len; ++i) {
        name += Ext.randArray(Localize.Words);
    }

    if (randValue < 50) {
        name += Ext.randArray(Localize.Symbols);
    }

    return name;
}

function generateRobotHeadpic() {
    return "BYY:HEADPIC:" + Ext.randRange(1, 51);
}

function generateRobotIP() {
    var ip = util.format("%d.%d.%d.%d", Ext.randRange(101, 183), Ext.randRange(10, 255), Ext.randRange(1, 150), Ext.randRange(1, 255));
    return ip;
}

function  RobotManager() {
    this.freeRobots = {};    // 空闲的机器人
    this.workRobots = {};    // 工作的机器人
    this.tickCount = 0;

    var robotScenes = [];
    ExObject.each(LogicSubModules, function(gameType, LogicModule) {
        var subTypes = LogicModule.Config.SubType;
        ExObject.each(subTypes, function(subType, subConfig) {
            if (!subConfig.scenes) {
                return;
            }

            ExObject.eachKeyNum(subConfig.scenes, function(scene, sceneConfig) {
                if (sceneConfig.robotSetting) {
                    robotScenes.push({
                        gameType: gameType,
                        subType: subType,
                        scene: scene,
                        config: sceneConfig,
                    });
                }
            })
        });
    });

    this.robotScenes = robotScenes;
}

RobotManager.prototype = {

    init: function(callback) {
        var cursor = DB.user.find({'robot':1}, {'_id':1});
        cursor.each(function(err, item) {
            if (err || !item) {
                callback && callback(err); return;
            }

            this.freeRobots[item._id] = 1;

            if (cursor.isClosed()) {
                callback && callback();
            }
        }.bind(this));
    },

    tick: function() {
        this.tickCount++;

        if (!this.robotScenes || this.robotScenes.length == 0) {
            return;
        }

        var freeRobotArray = Object.keys(this.freeRobots);
        if (freeRobotArray.length < 100) {
            for (var i = 0; i < 10; ++i) {
                this.addOneRobot();
            }
            return;
        }

        if (this.tickCount%2 != 0) {
            return;
        }

        this.robotScenes.forEach(function(robotScene) {
            var rooms = roomManager.getSceneRooms(robotScene.gameType, robotScene.subType, robotScene.scene);
            if (!rooms) {
                return;
            }

            ExObject.eachKeyNum(rooms, function(roomId, room) {
                this.tryEnterRoom(roomId, room, robotScene);
            }.bind(this));
        }.bind(this));
    },

    freeUser: function(uid) {
        logger.debug("world uid=%d robot free", uid);
        delete this.workRobots[uid];
        this.freeRobots[uid] = 1;
    },

    addOneRobot: function() {
        var openid = "BYY:ROBOT:" + ExNumber.randRange(1000, 9999);
        var self = this;

        gPlayerManger.addPlat(openid, function(err, uid) {
            if (err) {
                return;
            }

            gPlayerManger.getPlayer(uid, function(player) {
                if (!player) {
                    return;
                }

                if (player.isNew) {
                    var user = player.user;
                    user.robot = 1;
                    user.info.name = generateRobotName();
                    user.info.headpic = generateRobotHeadpic();
                    user.info.sex = Math.min(1, ExNumber.rand(3));
                    user.info.province = Ext.randArray(province);
                    user.info.createIP = generateRobotIP();

                    player.markDirty("robot");
                    player.markDirty("info");
                    player.save(true);
                    player.isNew = false;
                }

                if (self.freeRobots[uid] || self.workRobots[uid]) {
                    return;
                }

                self.freeRobots[uid] = 1;
            });
        }.bind(this));
    },

    tryEnterRoom: function(roomId, room, robotScene) {
        var userNum = room.users.length;
        if (userNum < 1 || userNum >= room.playerNum) {
            return;
        }

        var config = robotScene.config;
        var waitTime = config.robotSetting.waitTime;

        var nowStamp = Date.getStamp();
        if (nowStamp < room.updateTime + waitTime) {
            return;
        }

        var uidArray = Object.keys(this.freeRobots);
        if(uidArray.length < 1) {
            return;
        }

        var uid = +Ext.randArray(uidArray);
        delete this.freeRobots[uid];

        gPlayerManger.getPlayer(uid, function(player) {
            if (!player) {
                return;
            }
            var maxCoin = config.maxCoin;
            if(!maxCoin){
                maxCoin = 10000000;
            }
            var iCoin = Ext.randRange(config.minCoin, maxCoin);
            var curCoin = player.getResource("coin");
            var num = iCoin - curCoin;
            player.alterResourceNotSync(ExObject.build("coin", num), "robotTry");

            /*if (player.getResource("coin") < config.minCoin) {
                player.alterResourceNotSync(ExObject.build("coin", config.minCoin + Ext.randRange(5, 20)*config.scoreRate), "robotTry");
            }*/


            this._playerTryEnterRoom(player, roomId, room);
        }.bind(this));
    },

    _playerTryEnterRoom: function(player, roomId, room) {
        var uid = player.uid;

        var msg = {
            rid: roomId,
            gameType: room.gameType,
            subType: room.subType,
            scene: room.scene,
        }

        var session = new VirtualSession(uid);

        this.enter(msg, session, function(err, resp) {
            if (resp.code) {
                this.freeRobots[uid] = 1;
            } else {
                this.workRobots[uid] = 1;
            }
        }.bind(this));
    },

    enter: function(msg, session, next) {
        var uid = session.uid;
        var player = null;

        if (isNaN(msg.rid)) {
            next(null, {code: Code.ARGS_INVALID}); return;
        }

        var rid = +msg.rid;
        var oldRoomId = roomManager.getUserRoomId(uid);
        if (oldRoomId && oldRoomId != rid) {
            next(null, {code: Code.ALREADY_IN_ROOM}); return;
        }

        async.series([
            function(cb) {
                gPlayerManger.getPlayer(uid, function(thePlayer) {
                    if (!thePlayer) {
                        cb(Code.DB_ERROR); return;
                    }

                    player = thePlayer;
                    cb();
                });
            },
            function(cb) {
                session.set('rid', rid);
                msg.sid = session.frontendId;
                msg.user = player.buildGameUser(msg.gameType, msg.subType, msg.scene);
                pomelo.app.rpc.game.roomRemote.enter(session, uid, msg, function(code, resp) {
                    if (code) {
                        cb(code); return;
                    }

                    roomManager.userEnterRoom(uid, rid);
                    session.push('rid');

                    next(null, resp);
                    cb();
                });
            }
        ], function(code) {
            if(code) {
                next(null, {code: code, route:""});
            }

            if (player) {
                player.user.marks.loginTime = Date.getStamp();
                player.markDirty("marks");
            }
        });
    }
}

exports.RobotManager = RobotManager;